<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <base data-ice="baseUrl" href="../../">
  <title data-ice="title">src/Formio.unit.js | formiojs</title>
  <link type="text/css" rel="stylesheet" href="css/style.css">
  <link type="text/css" rel="stylesheet" href="css/prettify-tomorrow.css">
  <script src="script/prettify/prettify.js"></script>
  <script src="script/manual.js"></script>
<meta name="description" content="JavaScript powered Forms with JSON Form Builder"><meta property="twitter:card" content="summary"><meta property="twitter:title" content="formiojs"><meta property="twitter:description" content="JavaScript powered Forms with JSON Form Builder"></head>
<body class="layout-container" data-ice="rootContainer">

<header>
  <a href="./">Home</a>
  
  <a href="identifiers.html">Reference</a>
  <a href="source.html">Source</a>
  
  <div class="search-box">
  <span>
    <img src="./image/search.png">
    <span class="search-input-edge"></span><input class="search-input"><span class="search-input-edge"></span>
  </span>
    <ul class="search-result"></ul>
  </div>
<a style="position:relative; top:3px;" href="https://github.com/formio/formio.js"><img width="20px" src="./image/github.png"></a></header>

<nav class="navigation" data-ice="nav"><div>
  <ul>
    
  <li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/EventEmitter.js~EventEmitter.html">EventEmitter</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/Form.js~Form.html">Form</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/FormBuilder.js~FormBuilder.html">FormBuilder</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/Formio.js~Formio.html">Formio</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/PDF.js~PDF.html">PDF</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/PDFBuilder.js~PDFBuilder.html">PDFBuilder</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/Webform.js~Webform.html">Webform</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/WebformBuilder.js~WebformBuilder.html">WebformBuilder</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/Wizard.js~Wizard.html">Wizard</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/WizardBuilder.js~WizardBuilder.html">WizardBuilder</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#builders">builders</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/builders/Builders.js~Builders.html">Builders</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components">components</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/Components.js~Components.html">Components</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-component">components/_classes/component</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/component/Component.js~Component.html">Component</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Component">Component</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-component-editform">components/_classes/component/editForm</a><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-EditFormUtils">EditFormUtils</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-componentmodal">components/_classes/componentModal</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/componentModal/ComponentModal.js~ComponentModal.html">ComponentModal</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-field">components/_classes/field</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/field/Field.js~Field.html">Field</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-input">components/_classes/input</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/input/Input.js~Input.html">Input</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-multivalue">components/_classes/multivalue</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/multivalue/Multivalue.js~Multivalue.html">Multivalue</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-nested">components/_classes/nested</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/nested/NestedComponent.js~NestedComponent.html">NestedComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-NestedComponent">NestedComponent</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-nestedarray">components/_classes/nestedarray</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/nestedarray/NestedArrayComponent.js~NestedArrayComponent.html">NestedArrayComponent</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components--classes-nesteddata">components/_classes/nesteddata</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/_classes/nesteddata/NestedDataComponent.js~NestedDataComponent.html">NestedDataComponent</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-address">components/address</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/address/Address.js~AddressComponent.html">AddressComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Address">Address</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-AddressComponentMode">AddressComponentMode</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-button">components/button</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/button/Button.js~ButtonComponent.html">ButtonComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Button">Button</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-checkbox">components/checkbox</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/checkbox/Checkbox.js~CheckBoxComponent.html">CheckBoxComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Checkbox">Checkbox</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-columns">components/columns</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/columns/Columns.js~ColumnsComponent.html">ColumnsComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Columns">Columns</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-container">components/container</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/container/Container.js~ContainerComponent.html">ContainerComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Container">Container</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-content">components/content</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/content/Content.js~ContentComponent.html">ContentComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Content">Content</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-currency">components/currency</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/currency/Currency.js~CurrencyComponent.html">CurrencyComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Currency">Currency</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-datagrid">components/datagrid</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/datagrid/DataGrid.js~DataGridComponent.html">DataGridComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-DataGrid">DataGrid</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-datamap">components/datamap</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/datamap/DataMap.js~DataMapComponent.html">DataMapComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-DataMap">DataMap</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-datetime">components/datetime</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/datetime/DateTime.js~DateTimeComponent.html">DateTimeComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-DateTime">DateTime</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-day">components/day</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/day/Day.js~DayComponent.html">DayComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Day">Day</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-editgrid">components/editgrid</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/editgrid/EditGrid.js~EditGridComponent.html">EditGridComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-EditGrid">EditGrid</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-email">components/email</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/email/Email.js~EmailComponent.html">EmailComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Email">Email</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-fieldset">components/fieldset</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/fieldset/Fieldset.js~FieldsetComponent.html">FieldsetComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Fieldset">Fieldset</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-file">components/file</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/file/File.js~FileComponent.html">FileComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-File">File</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-form">components/form</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/form/Form.js~FormComponent.html">FormComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Form">Form</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-hidden">components/hidden</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/hidden/Hidden.js~HiddenComponent.html">HiddenComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Hidden">Hidden</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-html">components/html</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/html/HTML.js~HTMLComponent.html">HTMLComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-HTML">HTML</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-number">components/number</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/number/Number.js~NumberComponent.html">NumberComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Number">Number</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-panel">components/panel</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/panel/Panel.js~PanelComponent.html">PanelComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Panel">Panel</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-password">components/password</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/password/Password.js~PasswordComponent.html">PasswordComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Password">Password</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-phonenumber">components/phonenumber</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/phonenumber/PhoneNumber.js~PhoneNumberComponent.html">PhoneNumberComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-PhoneNumber">PhoneNumber</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-radio">components/radio</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/radio/Radio.js~RadioComponent.html">RadioComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Radio">Radio</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-recaptcha">components/recaptcha</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/recaptcha/ReCaptcha.js~ReCaptchaComponent.html">ReCaptchaComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-ReCaptcha">ReCaptcha</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-resource">components/resource</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/resource/Resource.js~ResourceComponent.html">ResourceComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Resource">Resource</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-select">components/select</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/select/Select.js~SelectComponent.html">SelectComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Select">Select</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-selectboxes">components/selectboxes</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/selectboxes/SelectBoxes.js~SelectBoxesComponent.html">SelectBoxesComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-SelectBoxes">SelectBoxes</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-signature">components/signature</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/signature/Signature.js~SignatureComponent.html">SignatureComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Signature">Signature</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-survey">components/survey</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/survey/Survey.js~SurveyComponent.html">SurveyComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Survey">Survey</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-table">components/table</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/table/Table.js~TableComponent.html">TableComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Table">Table</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-tabs">components/tabs</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/tabs/Tabs.js~TabsComponent.html">TabsComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Tabs">Tabs</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-tags">components/tags</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/tags/Tags.js~TagsComponent.html">TagsComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Tags">Tags</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-textarea">components/textarea</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/textarea/TextArea.js~TextAreaComponent.html">TextAreaComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-TextArea">TextArea</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-textfield">components/textfield</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/textfield/TextField.js~TextFieldComponent.html">TextFieldComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-TextField">TextField</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-time">components/time</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/time/Time.js~TimeComponent.html">TimeComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Time">Time</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-tree">components/tree</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/tree/Node.js~Node.html">Node</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/tree/Tree.js~TreeComponent.html">TreeComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Tree">Tree</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-unknown">components/unknown</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/unknown/Unknown.js~UnknownComponent.html">UnknownComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Unknown">Unknown</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-url">components/url</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/url/Url.js~UrlComponent.html">UrlComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Url">Url</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#components-well">components/well</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/components/well/Well.js~WellComponent.html">WellComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Well">Well</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib">contrib</a><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-Contrib">Contrib</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib-edittable">contrib/edittable</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/contrib/edittable/EditTable.js~EditTableComponent.html">EditTableComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-EditTable">EditTable</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib-location">contrib/location</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/contrib/location/Location.js~LocationComponent.html">LocationComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-Location">Location</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib-modaledit">contrib/modaledit</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/contrib/modaledit/ModalEdit.js~ModalEditComponent.html">ModalEditComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-ModalEdit">ModalEdit</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib-stripe-checkout">contrib/stripe/checkout</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/contrib/stripe/checkout/StripeCheckout.js~StripeCheckoutComponent.html">StripeCheckoutComponent</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#contrib-stripe-stripe">contrib/stripe/stripe</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/contrib/stripe/stripe/Stripe.js~StripeComponent.html">StripeComponent</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#displays">displays</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/displays/Displays.js~Displays.html">Displays</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#providers">providers</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/Providers.js~Providers.html">Providers</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#providers-address">providers/address</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/address/AddressProvider.js~AddressProvider.html">AddressProvider</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/address/AzureAddressProvider.js~AzureAddressProvider.html">AzureAddressProvider</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/address/CustomAddressProvider.js~CustomAddressProvider.html">CustomAddressProvider</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/address/GoogleAddressProvider.js~GoogleAddressProvider.html">GoogleAddressProvider</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/providers/address/NominatimAddressProvider.js~NominatimAddressProvider.html">NominatimAddressProvider</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#providers-storage">providers/storage</a><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-azure">azure</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-base64">base64</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-dropbox">dropbox</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-indexeddb">indexeddb</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-s3">s3</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-url">url</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-XHR">XHR</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#templates">templates</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/templates/Templates.js~Templates.html">Templates</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#templates-bootstrap">templates/bootstrap</a><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-iconClass">iconClass</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#utils">utils</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/utils/ChoicesWrapper.js~ChoicesWrapper.html">ChoicesWrapper</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkInvalidDate">checkInvalidDate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-lessOrGreater">lessOrGreater</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-applyFormChanges">applyFormChanges</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-eachComponent">eachComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-escapeRegExCharacters">escapeRegExCharacters</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-findComponent">findComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-findComponents">findComponents</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-flattenComponents">flattenComponents</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-formatAsCurrency">formatAsCurrency</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-generateFormChange">generateFormChange</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getComponent">getComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getStrings">getStrings</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getValue">getValue</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-hasCondition">hasCondition</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-isLayoutComponent">isLayoutComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-matchComponent">matchComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-parseFloatExt">parseFloatExt</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-removeComponent">removeComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-searchComponents">searchComponents</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-boolValue">boolValue</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-bootstrapVersion">bootstrapVersion</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkCalculated">checkCalculated</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkCondition">checkCondition</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkCustomConditional">checkCustomConditional</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkJsonConditional">checkJsonConditional</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkSimpleConditional">checkSimpleConditional</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-checkTrigger">checkTrigger</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-convertFormatToFlatpickr">convertFormatToFlatpickr</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-convertFormatToMask">convertFormatToMask</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-convertFormatToMoment">convertFormatToMoment</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-currentTimezone">currentTimezone</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-delay">delay</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-evaluate">evaluate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-fastCloneDeep">fastCloneDeep</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-fieldData">fieldData</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-formatDate">formatDate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-formatOffset">formatOffset</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getContextComponents">getContextComponents</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getCurrencyAffixes">getCurrencyAffixes</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getDateSetting">getDateSetting</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getElementRect">getElementRect</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getInputMask">getInputMask</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getLocaleDateFormatInfo">getLocaleDateFormatInfo</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getNumberDecimalLimit">getNumberDecimalLimit</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getNumberSeparators">getNumberSeparators</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getPropertyValue">getPropertyValue</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-getRandomComponentId">getRandomComponentId</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-guid">guid</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-isInputComponent">isInputComponent</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-isMongoId">isMongoId</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-isValidDate">isValidDate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-iterateKey">iterateKey</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-loadZones">loadZones</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-matchInputMask">matchInputMask</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-momentDate">momentDate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-observeOverload">observeOverload</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-offsetDate">offsetDate</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-sanitize">sanitize</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-setActionProperty">setActionProperty</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-shouldLoadZones">shouldLoadZones</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-unfold">unfold</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-uniqueKey">uniqueKey</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-uniqueName">uniqueName</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-withSwitch">withSwitch</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-function">F</span><span data-ice="name"><span><a href="function/index.html#static-function-zonesLoaded">zonesLoaded</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-KEY_CODES">KEY_CODES</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-Evaluator">Evaluator</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-CALENDAR_ERROR_MESSAGES">CALENDAR_ERROR_MESSAGES</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-firstNonNil">firstNonNil</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-interpolate">interpolate</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#utils-jsonlogic">utils/jsonlogic</a><span data-ice="kind" class="kind-variable">V</span><span data-ice="name"><span><a href="variable/index.html#static-variable-lodashOperators">lodashOperators</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#validator">validator</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/validator/Rules.js~Rules.html">Rules</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/validator/Validator.js~ValidationChecker.html">ValidationChecker</a></span></span></li>
<li data-ice="doc"><a data-ice="dirPath" class="nav-dir-path" href="identifiers.html#widgets">widgets</a><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/widgets/CalendarWidget.js~CalendarWidget.html">CalendarWidget</a></span></span></li>
<li data-ice="doc"><span data-ice="kind" class="kind-class">C</span><span data-ice="name"><span><a href="class/src/widgets/InputWidget.js~InputWidget.html">InputWidget</a></span></span></li>
</ul>
</div>
</nav>

<div class="content" data-ice="content"><h1 data-ice="title">src/Formio.unit.js</h1>
<pre class="source-code line-number raw-source-code"><code class="prettyprint linenums" data-ice="content">import Formio from &apos;./Formio&apos;;
import { fastCloneDeep } from &apos;./utils/utils&apos;;
import _each from &apos;lodash/each&apos;;
import assert from &apos;power-assert&apos;;
import sinon from &apos;sinon&apos;;
import Chance from &apos;chance&apos;;
import fetchMock from &apos;fetch-mock/es5/server&apos;;
import _ from &apos;lodash&apos;;
import NativePromise from &apos;native-promise-only&apos;;

const chance = Chance();
const protocol = &apos;https&apos;;
const domain = &apos;localhost:3000&apos;;
const baseUrl = `${protocol}://api.${domain}`;
Formio.setBaseUrl(baseUrl);
Formio.setToken(null);
Formio.fetch = fetchMock.fetchHandler;

const projectId = &apos;59bbe2ec8c246100079191aa&apos;;
const formId = &apos;59bbe2ec8c246100079191ab&apos;;
const submissionId = &apos;59bbe2ec8c246100079191ac&apos;;
const actionId = &apos;59bbe2ec8c246100079191ad&apos;;

const generateID = function() {
  return chance.string({ length: 24, pool: &apos;0123456789abcdef&apos; });
};

const runTests = function(fn, options) {
  const tests = {};
  const noBefore = fn(tests);
  if (!noBefore) {
    beforeEach(() =&gt; {
      Formio.setBaseUrl(baseUrl);
      Formio.projectUrlSet = false;
      Formio.projectUrl = &apos;https://api.form.io&apos;;
    });
  }
  _each(tests, (test, path) =&gt; {
    it(`Should initialize for ${path}`, (done) =&gt; {
      if (typeof test === &apos;function&apos;) {
        test();
      }
      else {
        const formio = new Formio(path, options);
        for (const param in test) {
          assert.equal(formio[param], test[param], `${param} is not equal. ${formio[param]} == ${test[param]}\n`);
        }
      }
      done();
    });
  });
};

describe(&apos;Formio.js Tests&apos;, () =&gt; {
  describe(&apos;Formio Constructor Tests&apos;, () =&gt; {
    runTests((tests) =&gt; {
      tests[`http://form.io/project/${  projectId  }/form/${  formId}`] = {
        projectUrl: `http://form.io/project/${  projectId}`,
        projectsUrl: &apos;http://form.io/project&apos;,
        projectId: projectId,
        formsUrl: `http://form.io/project/${  projectId  }/form`,
        formUrl: `http://form.io/project/${  projectId  }/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://form.io/form/${  formId}`] = {
        projectUrl: &apos;http://form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;&apos;,
        formsUrl: &apos;http://form.io/form&apos;,
        formUrl: `http://form.io/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/form/${  formId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://form.io/form/${  formId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://form.io/form/${  formId  }/submission/${  submissionId}`] = {
        projectUrl: &apos;http://form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;&apos;,
        formsUrl: &apos;http://form.io/form&apos;,
        formUrl: `http://form.io/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/form/${  formId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://form.io/form/${  formId  }/submission`,
        submissionUrl: `http://form.io/form/${  formId  }/submission/${  submissionId}`,
        submissionId: submissionId,
        query: &apos;&apos;
      };
      tests[`http://form.io/form/${  formId  }/action/${  actionId}`] = {
        projectUrl: &apos;http://form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;&apos;,
        formsUrl: &apos;http://form.io/form&apos;,
        formUrl: `http://form.io/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/form/${  formId  }/action`,
        actionUrl: `http://form.io/form/${  formId  }/action/${  actionId}`,
        actionId: actionId,
        submissionsUrl: `http://form.io/form/${  formId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://form.io/project/${  projectId  }/form/${  formId  }/action/${  actionId}`] = {
        projectUrl: `http://form.io/project/${  projectId}`,
        projectsUrl: &apos;http://form.io/project&apos;,
        projectId: projectId,
        formsUrl: `http://form.io/project/${  projectId  }/form`,
        formUrl: `http://form.io/project/${  projectId  }/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/action`,
        actionUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/action/${  actionId}`,
        actionId: actionId,
        submissionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://api.form.io/project/${  projectId}`] = {
        projectUrl: `http://api.form.io/project/${  projectId}`,
        projectsUrl: &apos;http://api.form.io/project&apos;,
        projectId: projectId,
        formsUrl: `http://api.form.io/project/${  projectId  }/form`,
        formUrl: &apos;&apos;,
        formId: &apos;&apos;,
        actionsUrl: `http://api.form.io/project/${  projectId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://api.form.io/project/${  projectId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://form.io/project/${  projectId  }/form/${  formId  }/submission/${  submissionId}`] = {
        projectUrl: `http://form.io/project/${  projectId}`,
        projectsUrl: &apos;http://form.io/project&apos;,
        projectId: projectId,
        formsUrl: `http://form.io/project/${  projectId  }/form`,
        formUrl: `http://form.io/project/${  projectId  }/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/submission`,
        submissionUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/submission/${  submissionId}`,
        submissionId: submissionId,
        query: &apos;&apos;
      };
      tests[`http://form.io/project/${  projectId  }/form/${  formId  }?test=hello&amp;test2=there`] = {
        projectUrl: `http://form.io/project/${  projectId}`,
        projectsUrl: &apos;http://form.io/project&apos;,
        projectId: projectId,
        formsUrl: `http://form.io/project/${  projectId  }/form`,
        formUrl: `http://form.io/project/${  projectId  }/form/${  formId}`,
        formId: formId,
        actionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `http://form.io/project/${  projectId  }/form/${  formId  }/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=hello&amp;test2=there&apos;
      };
      tests[&apos;http://project.form.io/user/login&apos;] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/login&apos;,
        formId: &apos;user/login&apos;,
        actionsUrl: &apos;http://project.form.io/user/login/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/login/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://project.form.io/user/login/submission/${  submissionId}`] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/login&apos;,
        formId: &apos;user/login&apos;,
        actionsUrl: &apos;http://project.form.io/user/login/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/login/submission&apos;,
        submissionUrl: `http://project.form.io/user/login/submission/${  submissionId}`,
        submissionId: submissionId,
        query: &apos;&apos;
      };
      tests[`http://project.form.io/user/login/action/${  actionId}`] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/login&apos;,
        formId: &apos;user/login&apos;,
        actionsUrl: &apos;http://project.form.io/user/login/action&apos;,
        actionUrl: `http://project.form.io/user/login/action/${  actionId}`,
        actionId: actionId,
        submissionsUrl: &apos;http://project.form.io/user/login/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://project.form.io/user/login/action/${  actionId  }?test=test2`] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/login&apos;,
        formId: &apos;user/login&apos;,
        actionsUrl: &apos;http://project.form.io/user/login/action&apos;,
        actionUrl: `http://project.form.io/user/login/action/${  actionId}`,
        actionId: actionId,
        submissionsUrl: &apos;http://project.form.io/user/login/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=test2&apos;
      };
      tests[`http://project.form.io/user/loginform/action/${  actionId  }?test=test2`] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/loginform&apos;,
        formId: &apos;user/loginform&apos;,
        actionsUrl: &apos;http://project.form.io/user/loginform/action&apos;,
        actionUrl: `http://project.form.io/user/loginform/action/${  actionId}`,
        actionId: actionId,
        submissionsUrl: &apos;http://project.form.io/user/loginform/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=test2&apos;
      };
      tests[&apos;http://project.form.io/user/loginform/submission&apos;] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/loginform&apos;,
        formId: &apos;user/loginform&apos;,
        actionsUrl: &apos;http://project.form.io/user/loginform/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/loginform/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[&apos;http://project.form.io/user&apos;] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user&apos;,
        formId: &apos;user&apos;,
        actionsUrl: &apos;http://project.form.io/user/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`http://project.form.io/user/actionform/submission/${  submissionId}`] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/actionform&apos;,
        formId: &apos;user/actionform&apos;,
        actionsUrl: &apos;http://project.form.io/user/actionform/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/actionform/submission&apos;,
        submissionUrl: `http://project.form.io/user/actionform/submission/${  submissionId}`,
        submissionId: submissionId,
        query: &apos;&apos;
      };
      tests[&apos;http://project.form.io/user/actionform/?test=foo&apos;] = {
        projectUrl: &apos;http://project.form.io&apos;,
        projectsUrl: `${baseUrl}/project`,
        projectId: &apos;project&apos;,
        formsUrl: &apos;http://project.form.io/form&apos;,
        formUrl: &apos;http://project.form.io/user/actionform&apos;,
        formId: &apos;user/actionform&apos;,
        actionsUrl: &apos;http://project.form.io/user/actionform/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;http://project.form.io/user/actionform/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=foo&apos;
      };
    });
  });

  describe(&apos;Localhost Constructor Tests&apos;, () =&gt; {
    const testBaseUrl = &apos;localhost:3000&apos;;
    const projectName = &apos;myproject&apos;;
    const projectUrl = `${protocol}://${projectName}.${testBaseUrl}`;
    runTests((tests) =&gt; {
      tests[`${projectUrl}/user/actionform/?test=foo`] = {
        projectUrl: projectUrl,
        projectsUrl: `${baseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user/actionform`,
        formId: &apos;user/actionform&apos;,
        actionsUrl: `${projectUrl}/user/actionform/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/actionform/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=foo&apos;
      };
      tests[`${projectUrl}/user`] = {
        projectUrl: projectUrl,
        projectsUrl: `${baseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user`,
        formId: &apos;user&apos;,
        actionsUrl: `${projectUrl}/user/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
    }, { base: baseUrl });
  });

  describe(&apos;Subdomain Constructor Tests&apos;, () =&gt; {
    const testBaseUrl = &apos;foo.blah.form.io&apos;;
    const projectName = &apos;myproject&apos;;
    const projectUrl = `${protocol}://${projectName}.${testBaseUrl}`;
    runTests((tests) =&gt; {
      tests[`${projectUrl}/user/actionform/?test=foo`] = {
        projectUrl: projectUrl,
        projectsUrl: `${baseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user/actionform`,
        formId: &apos;user/actionform&apos;,
        actionsUrl: `${projectUrl}/user/actionform/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/actionform/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=foo&apos;
      };
      tests[`${projectUrl}/user`] = {
        projectUrl: projectUrl,
        projectsUrl: `${baseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user`,
        formId: &apos;user&apos;,
        actionsUrl: `${projectUrl}/user/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
    }, { base: baseUrl });
  });

  describe(&apos;Subdirectory Constructor Tests&apos;, () =&gt; {
    const testBaseUrl = &apos;foo.blah.form.io&apos;;
    const projectName = &apos;myproject&apos;;
    const projectUrl = `${protocol}://${testBaseUrl}/${projectName}`;
    runTests((tests) =&gt; {
      tests[`${projectUrl}/user/actionform/?test=foo`] = {
        projectUrl: projectUrl,
        projectsUrl: `${protocol}://${testBaseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user/actionform`,
        formId: &apos;user/actionform&apos;,
        actionsUrl: `${projectUrl}/user/actionform/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/actionform/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=foo&apos;
      };
      tests[`${projectUrl}/user`] = {
        projectUrl: projectUrl,
        projectsUrl: `${protocol}://${testBaseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: `${projectUrl}/user`,
        formId: &apos;user&apos;,
        actionsUrl: `${projectUrl}/user/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/user/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[projectUrl] = {
        projectUrl: projectUrl,
        projectsUrl: `${protocol}://${testBaseUrl}/project`,
        projectId: projectName,
        formsUrl: `${projectUrl}/form`,
        formUrl: &apos;&apos;,
        formId: &apos;&apos;,
        actionsUrl: `${projectUrl}/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${projectUrl}/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
    }, { base: `${protocol}://${testBaseUrl}` });
  });

  describe(&apos;Simple Form Constructor Tests&apos;, () =&gt; {
    runTests((tests) =&gt; {
      tests[&apos;init&apos;] = () =&gt; {
        Formio.setBaseUrl(&apos;https://api.form.io&apos;);
        Formio.projectUrlSet = false;
        Formio.projectUrl = &apos;https://api.form.io&apos;;
      };
      tests[&apos;https://examples.form.io/example&apos;] = {
        projectUrl: &apos;https://examples.form.io&apos;,
        projectsUrl: &apos;&apos;,
        projectId: &apos;&apos;,
        formsUrl: &apos;https://examples.form.io/form&apos;,
        formUrl: &apos;https://examples.form.io/example&apos;,
        formId: &apos;example&apos;,
        actionsUrl: &apos;https://examples.form.io/example/action&apos;,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: &apos;https://examples.form.io/example/submission&apos;,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      return true;
    });
  });

  describe(&apos;Open Source Constructor Tests&apos;, () =&gt; {
    const formBaseUrl = &apos;http://localhost:3000&apos;;
    runTests((tests) =&gt; {
      tests[`${formBaseUrl}/user`] = {
        projectUrl: formBaseUrl,
        projectsUrl: &apos;&apos;,
        projectId: &apos;&apos;,
        formsUrl: `${formBaseUrl}/form`,
        formUrl: `${formBaseUrl}/user`,
        formId: &apos;user&apos;,
        actionsUrl: `${formBaseUrl}/user/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${formBaseUrl}/user/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;&apos;
      };
      tests[`${formBaseUrl}/user/actionform/?test=foo`] = {
        projectUrl: formBaseUrl,
        projectsUrl: &apos;&apos;,
        projectId: &apos;&apos;,
        formsUrl: `${formBaseUrl}/form`,
        formUrl: `${formBaseUrl}/user/actionform`,
        formId: &apos;user/actionform&apos;,
        actionsUrl: `${formBaseUrl}/user/actionform/action`,
        actionUrl: &apos;&apos;,
        actionId: &apos;&apos;,
        submissionsUrl: `${formBaseUrl}/user/actionform/submission`,
        submissionUrl: &apos;&apos;,
        submissionId: &apos;&apos;,
        query: &apos;?test=foo&apos;
      };
    }, { base: formBaseUrl, project: formBaseUrl });
  });

  describe(&apos;Plugins&apos;, () =&gt; {
    let plugin = null;
    beforeEach(() =&gt; {
      assert.equal(Formio.getPlugin(&apos;test-plugin&apos;), undefined, &apos;No plugin may be returned under the name `test-plugin`&apos;);
      plugin = { init: sinon.spy() };
      Formio.registerPlugin(plugin, &apos;test-plugin&apos;);
      assert.ok(plugin.init.calledOnce, &apos;plugin.init must be called exactly once&apos;);
      assert.ok(plugin.init.calledOn(plugin), &apos;plugin.init must be called on plugin as `this`&apos;);
      assert.ok(plugin.init.calledWithExactly(Formio), &apos;plugin.init must be given Formio as argument&apos;);
      assert.equal(Formio.getPlugin(&apos;test-plugin&apos;), plugin, &apos;getPlugin must return plugin&apos;);
    });

    afterEach(() =&gt; {
      assert.equal(Formio.getPlugin(&apos;test-plugin&apos;), plugin, &apos;getPlugin must return plugin&apos;);
      plugin.deregister = sinon.spy();
      Formio.deregisterPlugin(plugin, &apos;test-plugin&apos;);
      assert.ok(plugin.deregister.calledOnce, &apos;plugin.deregister must be called exactly once&apos;);
      assert.ok(plugin.deregister.calledOn(plugin), &apos;plugin.deregister must be called on plugin as `this`&apos;);
      assert.ok(plugin.deregister.calledWithExactly(Formio), &apos;plugin.deregister must be given Formio as argument&apos;);
      assert.equal(Formio.getPlugin(&apos;test-plugin&apos;), undefined, &apos;No plugin may be returned under the name `test-plugin`&apos;);
    });

    // Test a request to see if the plugin flow order is correct
    const testRequest = function testRequest(url, method, type) {
      let fnName;
      switch (method) {
        case &apos;GET&apos;: fnName = `load${_.capitalize(type)}`; break;
        case &apos;POST&apos;:
        case &apos;PUT&apos;: fnName = `save${_.capitalize(type)}`; break;
        case &apos;DELETE&apos;: fnName = `delete${_.capitalize(type)}`; break;
      }

      it(`Plugin ${method} ${fnName}`, (done) =&gt; {
        let step = 0;
        const formio = new Formio(url);
        method = method.toUpperCase();
        const testData = { testRequest: &apos;TEST_REQUEST&apos; };
        const testOpts = { testOption: true };
        const testResult = { _id: &apos;TEST_ID&apos;, testResult: &apos;TEST_RESULT&apos; };

        const expectedArgs = {
          formio: formio,
          type: type,
          method: method,
          url: formio[type + (method === &apos;POST&apos; ? &apos;sUrl&apos; : &apos;Url&apos;)],
          data: _.startsWith(fnName, &apos;save&apos;) ? testData : null,
          opts: testOpts
        };

        // Set up plugin hooks
        plugin.preRequest = function(requestArgs) {
          assert.equal(++step, 1, &apos;preRequest hook should be called first&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 3, &apos;preRequest promise should resolve third&apos;);
              // TODO
            });
        };
        plugin.request = function(requestArgs) {
          assert.equal(++step, 4, &apos;request hook should be called fourth&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 5, &apos;request promise should resolve fifth&apos;);
              return testResult;
            });
        };
        plugin.wrapRequestPromise = function(promise, requestArgs) {
          assert.equal(++step, 2, &apos;wrapRequestPromise hook should be called second&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return promise.then((result) =&gt; {
            assert.equal(++step, 6, &apos;wrapRequestPromise post-result promise should resolve sixth&apos;);
            assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
            return result;
          });
        };

        let promise;
        if (_.startsWith(fnName, &apos;save&apos;)) {
          promise = formio[fnName](testData, testOpts);
        }
        else if (_.startsWith(fnName, &apos;load&apos;)) {
          promise = formio[fnName](null, testOpts);
        }
        else {
          promise = formio[fnName](testOpts);
        }
        promise.then((result) =&gt; {
          assert.equal(++step, 7, &apos;post request promise should resolve last&apos;);
          assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
          done();
        });
      });
    };

    const tests = [
      {
        url: &apos;https://api.localhost:3000/project/myproject&apos;,
        method: &apos;GET&apos;,
        type: &apos;project&apos;
      },
      {
        url: &apos;&apos;,
        method: &apos;POST&apos;,
        type: &apos;project&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject&apos;,
        method: &apos;PUT&apos;,
        type: &apos;project&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject&apos;,
        method: &apos;DELETE&apos;,
        type: &apos;project&apos;
      },

      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;GET&apos;,
        type: &apos;form&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject&apos;,
        method: &apos;POST&apos;,
        type: &apos;form&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;PUT&apos;,
        type: &apos;form&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;DELETE&apos;,
        type: &apos;form&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/&apos;,
        method: &apos;GET&apos;,
        type: &apos;forms&apos;
      },

      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210&apos;,
        method: &apos;GET&apos;,
        type: &apos;submission&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;POST&apos;,
        type: &apos;submission&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210&apos;,
        method: &apos;PUT&apos;,
        type: &apos;submission&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/submission/76543210FEDCBA9876543210&apos;,
        method: &apos;DELETE&apos;,
        type: &apos;submission&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;GET&apos;,
        type: &apos;submissions&apos;
      },

      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210&apos;,
        method: &apos;GET&apos;,
        type: &apos;action&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;POST&apos;,
        type: &apos;action&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210&apos;,
        method: &apos;PUT&apos;,
        type: &apos;action&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567/action/76543210FEDCBA9876543210&apos;,
        method: &apos;DELETE&apos;,
        type: &apos;action&apos;
      },
      {
        url: &apos;https://api.localhost:3000/project/myproject/form/0123456789ABCDEF01234567&apos;,
        method: &apos;GET&apos;,
        type: &apos;actions&apos;
      }
    ];

    tests.forEach((test) =&gt; {
      testRequest(test.url, test.method, test.type);
    });

    const testStaticRequest = function testStaticRequest(fnName, url, method) {
      it(`Plugin ${fnName}`, (done) =&gt; {
        let step = 0;
        const testResult = { _id: &apos;TEST_ID&apos;, testResult: &apos;TEST_RESULT&apos; };
        const expectedArgs = {
          url: url,
          method: method,
          data: null,
          opts: {}
        };

        // Set up plugin hooks
        plugin.preRequest = function(requestArgs) {
          assert.equal(++step, 1, &apos;preRequest hook should be called first&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 3, &apos;preRequest promise should resolve third&apos;);
              // TODO
            });
        };
        plugin.staticRequest = function(requestArgs) {
          assert.equal(++step, 4, &apos;request hook should be called fourth&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 5, &apos;request promise should resolve fifth&apos;);
              return testResult;
            });
        };
        plugin.wrapStaticRequestPromise = function(promise, requestArgs) {
          assert.equal(++step, 2, &apos;wrapRequestPromise hook should be called second&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return promise.then((result) =&gt; {
            assert.equal(++step, 6, &apos;wrapRequestPromise post-result promise should resolve sixth&apos;);
            assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
            return result;
          });
        };

        Formio[fnName]()
          .then((result) =&gt; {
            assert.equal(++step, 7, &apos;post request promise should resolve last&apos;);
            assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
            done();
          });
      });
    };

    const staticTests = [
      {
        fnName: &apos;loadProjects&apos;,
        url: &apos;https://api.localhost:3000/project&apos;,
        method: &apos;GET&apos;
      },
      {
        fnName: &apos;logout&apos;,
        url: &apos;https://api.localhost:3000/logout&apos;,
        method: &apos;GET&apos;
      }
    ];

    staticTests.forEach((test) =&gt; {
      testStaticRequest(test.fnName, test.url, test.method, test.type);
    });

    const testFileRequest = function testFileRequest(fnName, formUrl, args) {
      it(`Plugin ${fnName}`, (done) =&gt; {
        let step = 0;
        const testResult = { _id: &apos;TEST_ID&apos;, testResult: &apos;TEST_RESULT&apos; };
        let expectedArgs;

        if (fnName === &apos;downloadFile&apos;) {
          expectedArgs = {
            method: &apos;download&apos;,
            file: args[0]
          };
        }
        else if (fnName === &apos;uploadFile&apos;) {
          expectedArgs = {
            provider: args[0],
            method: &apos;upload&apos;,
            file: args[1],
            fileName: args[2],
            dir: args[3]
          };
        }

        // Set up plugin hooks
        plugin.preRequest = function(requestArgs) {
          assert.equal(++step, 1, &apos;preRequest hook should be called first&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 3, &apos;preRequest promise should resolve third&apos;);
              // TODO
            });
        };
        plugin.fileRequest = function(requestArgs) {
          assert.equal(++step, 4, &apos;request hook should be called fourth&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return NativePromise.resolve()
            .then(() =&gt; {
              assert.equal(++step, 5, &apos;request promise should resolve fifth&apos;);
              return testResult;
            });
        };
        plugin.wrapFileRequestPromise = function(promise, requestArgs) {
          assert.equal(++step, 2, &apos;wrapFileRequestPromise hook should be called second&apos;);
          assert.deepEqual(requestArgs, expectedArgs, &apos;Request hook arguments match expected arguments&apos;);
          return promise.then((result) =&gt; {
            assert.equal(++step, 6, &apos;wrapFileRequestPromise post-result promise should resolve sixth&apos;);
            assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
            return result;
          });
        };

        const formio = new Formio(formUrl);
        formio[fnName].apply(null, args)
          .then((result) =&gt; {
            assert.equal(++step, 7, &apos;post request promise should resolve last&apos;);
            assert.deepEqual(result, testResult, &apos;Result should match result from request hook&apos;);
            done();
          });
      });
    };

    const fileTests = [
      {
        fnName: &apos;uploadFile&apos;,
        formUrl: &apos;https://api.localhost:3000/project/123/form/123&apos;,
        args: [
          &apos;s3&apos;,
          &apos;FILE&apos;,
          &apos;file.jpg&apos;,
          &apos;dir/&apos;
        ]
      },
      {
        fnName: &apos;uploadFile&apos;,
        formUrl: &apos;https://api.localhost:3000/project/123/form/123&apos;,
        args: [
          &apos;dropbox&apos;,
          &apos;FILE&apos;,
          &apos;file.jpg&apos;,
          &apos;dir/&apos;
        ]
      },
      {
        fnName: &apos;downloadFile&apos;,
        formUrl: &apos;https://api.localhost:3000/project/123/form/123&apos;,
        args: [
          {
            storage: &apos;s3&apos;,
            name: &apos;test&apos;
          }
        ]
      },
      {
        fnName: &apos;downloadFile&apos;,
        formUrl: &apos;https://api.localhost:3000/project/123/form/123&apos;,
        args: [
          {
            storage: &apos;dropbox&apos;,
            name: &apos;test&apos;
          }
        ]
      }
    ];

    fileTests.forEach((test) =&gt; {
      testFileRequest(test.fnName, test.formUrl, test.args);
    });
  });

  describe(&apos;Test Formio.js capabilities&apos;, () =&gt; {
    const testCapability = function(test) {
      it(test.name, (done) =&gt; {
        // need to clear Formio cache before every test, otherwise mock results might be ignored for same URLs
        Formio.clearCache();
        if (test.mock) {
          const mock = test.mock();
          if (mock instanceof Array) {
            _.each(mock, (_mock) =&gt; {
              fetchMock.mock(_mock.url, _mock.response, { method: _mock.method });
            });
          }
          else {
            fetchMock.mock(mock.url, mock.response, { method: mock.method });
          }
        }
        NativePromise.resolve()
          .then(() =&gt; {
            return test.test();
          })
          .then(() =&gt; {
            if (test.mock) {
              fetchMock.restore();
            }
            done();
          })
          .catch((err) =&gt; {
            if (test.mock) {
              fetchMock.restore();
            }
            done(typeof err === &apos;string&apos; ? new Error(err) : err);
          });
      });
    };

    let user;
    let userPassword;
    let userToken = chance.string({ length: 450 });
    const userFormId = generateID();
    let project;
    let form;
    let submission;

    const tests = [
      {
        name: &apos;Registering user.&apos;,
        test() {
          const req = {
            data: {
              &apos;user.name&apos;: chance.string({
                length: 10,
                pool: &apos;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&apos;
              }),
              &apos;user.email&apos;: chance.email(),
              &apos;user.password&apos;: chance.string({ length: 12 })
            }
          };
          Formio.setProjectUrl(Formio.getBaseUrl());
          const formio = new Formio(`${Formio.getBaseUrl()}/user/register`);
          return formio.saveSubmission(req)
            .then((response) =&gt; {
              assert.deepEqual(response, user, &apos;saveSubmission response should match test user&apos;);
              assert.equal(Formio.getToken(), userToken, &apos;Formio should save the user token&apos;);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/current`,
              method: &apos;GET&apos;,
              response() {
                return {
                  headers: {
                    &apos;Content-Type&apos;: &apos;application/json&apos;,
                    &apos;x-jwt-token&apos;: userToken
                  },
                  body: user
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/user/register/submission`,
              method: &apos;POST&apos;,
              response(url, opts) {
                const body = JSON.parse(opts.body);
                const userId = generateID();
                user = {
                  _id: userId,
                  created: new Date().toISOString(),
                  modified: new Date().toISOString(),
                  data: {
                    email: body.data[&apos;user.email&apos;],
                    name: body.data[&apos;user.name&apos;]
                  },
                  externalIds: [],
                  externalTokens: [],
                  form: userFormId,
                  owner: userId
                };
                userPassword = body.data[&apos;user.password&apos;];
                return {
                  headers: {
                    &apos;Content-Type&apos;: &apos;application/json&apos;,
                    &apos;x-jwt-token&apos;: userToken
                  },
                  body: user
                };
              }
            }
          ];
        }
      },
      {
        name: &apos;Logging in.&apos;,
        test() {
          const req = {
            data: {
              &apos;user.email&apos;: user.data.email,
              &apos;user.password&apos;: userPassword
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/user/login`);
          return formio.saveSubmission(req)
            .then((response) =&gt; {
              assert.deepEqual(response, user, &apos;saveSubmission response should match test user&apos;);
              assert.equal(Formio.getToken(), userToken, &apos;Formio should save the user token&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/user/login/submission`,
            method: &apos;POST&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              userToken = chance.string({ length: 450 });
              assert.equal(body.data[&apos;user.email&apos;], user.data.email, &apos;Login email must be correct.&apos;);
              assert.equal(body.data[&apos;user.password&apos;], userPassword, &apos;Login password must be correct.&apos;);
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: user
              };
            }
          };
        }
      },
      {
        name: &apos;Current user.&apos;,
        test() {
          return Formio.currentUser()
            .then((response) =&gt; {
              assert.deepEqual(response, user, &apos;currentUser response should match test user&apos;);
              return Formio.currentUser();
            })
            .then((response) =&gt; {
              assert.deepEqual(response, user, &apos;currentUser response should match test user&apos;);
            });
        },
        mock() {
          let called = false;
          return {
            url: `${Formio.getBaseUrl()}/current`,
            method: &apos;GET&apos;,
            response() {
              assert.ok(!called, &apos;User should be requested only once.&apos;);
              called = true;
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: user
              };
            }
          };
        }
      },
      {
        name: &apos;Create Project&apos;,
        test() {
          const formio = new Formio();
          const req = {
            title: chance.string({
              length: 10,
              pool: &apos;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&apos;
            }),
            name: chance.string({
              length: 10,
              pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
            }),
            description: chance.paragraph({ sentences: 1 }),
            settings: {
              cors: &apos;*&apos;
            },
            template: &apos;http://help.form.io/templates/empty.json&apos;
          };
          return formio.saveProject(req)
            .then((response) =&gt; {
              assert.deepEqual(response, project, &apos;saveProject response should match test user&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project`,
            method: &apos;POST&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              const projectId = generateID();
              project = {
                _id: projectId,
                created: new Date().toISOString(),
                modified: new Date().toISOString(),
                apiCalls: {
                  used: 0,
                  limit: 1000,
                  remaining: 1000,
                  reset: new Date(Date.now() + 2.628e9).toISOString() // ~1 month later
                },
                access: [],
                title: body.title,
                name: body.name,
                description: body.description,
                plan: &apos;basic&apos;,
                owner: user._id
              };
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: project
              };
            }
          };
        }
      },
      {
        name: &apos;Getting Projects&apos;,
        test() {
          return Formio.loadProjects()
            .then((projects) =&gt; {
              assert.equal(projects.length, 1, &apos;Should return only one project.&apos;);
              assert.equal(projects.skip, 0, &apos;skip should be 0.&apos;);
              assert.equal(projects.limit, 1, &apos;limit should be 1.&apos;);
              assert.equal(projects.serverCount, 1, &apos;serverCount should be 1.&apos;);
              assert.deepEqual(projects[0], project, &apos;Should match project&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;Content-Range&apos;: &apos;0-0/1&apos;,
                  &apos;Range-Unit&apos;: &apos;items&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: [project]
              };
            }
          };
        }
      },
      {
        name: &apos;Read Project&apos;,
        test() {
          const formio = new Formio(`${Formio.getBaseUrl()}/project/${project._id}`);
          return formio.loadProject()
            .then((response) =&gt; {
              assert.deepEqual(response, project, &apos;Should match project&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: project
              };
            }
          };
        }
      },
      {
        name: &apos;Update Project&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}`);
          const newProject = fastCloneDeep(project);
          newProject.name = chance.string({
            length: 10,
            pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
          });
          newProject.title = chance.string({
            length: 10,
            pool: &apos;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&apos;
          });
          newProject.description = chance.paragraph({ sentences: 1 });
          return formio.saveProject(newProject)
            .then((response) =&gt; {
              assert.deepEqual(response, project, &apos;Project should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}`,
            method: &apos;PUT&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              project = body;
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: project
              };
            }
          };
        }
      },
      {
        name: &apos;Create Form&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form`);
          const req = {
            title: chance.string({
              length: 10,
              pool: &apos;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&apos;
            }),
            name: chance.string({
              length: 10,
              pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
            }),
            path: chance.string({
              length: 10,
              pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
            }),
            components: [
              {
                defaultValue: &apos;&apos;,
                input: true,
                inputMask: &apos;&apos;,
                inputType: &apos;text&apos;,
                isNew: false,
                key: &apos;fieldLabel&apos;,
                label: &apos;Field Label&apos;,
                multiple: false,
                persistent: true,
                placeholder: &apos;&apos;,
                prefix: &apos;&apos;,
                protected: false,
                suffix: &apos;&apos;,
                tableView: true,
                type: &apos;textfield&apos;,
                unique: false,
                validate: {
                  required: false,
                  minLength: &apos;&apos;,
                  maxLength: &apos;&apos;,
                  pattern: &apos;&apos;,
                  custom: &apos;&apos;,
                  customPrivate: false
                }
              },
              {
                action: &apos;submit&apos;,
                block: false,
                disableOnInvalid: true,
                input: true,
                key: &apos;submit&apos;,
                label: &apos;Submit&apos;,
                leftIcon: &apos;&apos;,
                rightIcon: &apos;&apos;,
                size: &apos;md&apos;,
                tableView: false,
                theme: &apos;primary&apos;,
                type: &apos;button&apos;
              }
            ],
            type: &apos;form&apos;,
            access: [],
            submissionAccess: []
          };
          return formio.saveForm(req)
            .then((response) =&gt; {
              assert.deepEqual(response, form, &apos;Form should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form`,
            method: &apos;POST&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              const formId = generateID();
              form = fastCloneDeep(body);
              _.assign(form, {
                _id: formId,
                created: new Date().toISOString(),
                modified: new Date().toISOString(),
                project: project._id,
                owner: user._id
              });
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: form
              };
            }
          };
        }
      },
      {
        name: &apos;Load Forms&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form`);
          return formio.loadForms()
            .then((forms) =&gt; {
              assert.equal(forms.length, 1, &apos;Should return only one form.&apos;);
              assert.equal(forms.skip, 0, &apos;skip should be 0.&apos;);
              assert.equal(forms.limit, 1, &apos;limit should be 1.&apos;);
              assert.equal(forms.serverCount, 1, &apos;serverCount should be 1.&apos;);
              assert.deepEqual(forms[0], form, &apos;Should match form&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;Content-Range&apos;: &apos;0-0/1&apos;,
                  &apos;Range-Unit&apos;: &apos;items&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: [form]
              };
            }
          };
        }
      },
      {
        name: &apos;Read Form&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}`);
          return formio.loadForm()
            .then((response) =&gt; {
              assert.deepEqual(response, form, &apos;Form should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: form
              };
            }
          };
        }
      },
      {
        name: &apos;Update Form&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}`);
          const newForm = fastCloneDeep(form);
          newForm.title = chance.string({
            length: 10,
            pool: &apos;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&apos;
          });
          newForm.name = chance.string({
            length: 10,
            pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
          });
          newForm.path = chance.string({
            length: 10,
            pool: &apos;abcdefghijklmnopqrstuvwxyz&apos;
          });
          return formio.saveForm(newForm)
            .then((response) =&gt; {
              assert.deepEqual(response, form, &apos;Form should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
            method: &apos;PUT&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              form = body;
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: form
              };
            }
          };
        }
      },
      {
        name: &apos;Create Submission&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}/submission`);
          const req = {
            data: {
              fieldLabel: chance.string()
            }
          };
          return formio.saveSubmission(req)
            .then((response) =&gt; {
              assert.deepEqual(response, submission, &apos;Submission should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission`,
            method: &apos;POST&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              const submissionId = generateID();
              submission = {
                _id: submissionId,
                created: new Date().toISOString(),
                modified: new Date().toISOString(),
                data: body.data,
                externalIds: [],
                externalTokens: [],
                form: form._id,
                owner: user._id,
                roles: []
              };
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: submission
              };
            }
          };
        }
      },
      {
        name: &apos;Load Submissions&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}/submission`);
          return formio.loadSubmissions()
            .then((submissions) =&gt; {
              assert.equal(submissions.length, 1, &apos;Should return only one submission.&apos;);
              assert.equal(submissions.skip, 0, &apos;skip should be 0.&apos;);
              assert.equal(submissions.limit, 1, &apos;limit should be 1.&apos;);
              assert.equal(submissions.serverCount, 1, &apos;serverCount should be 1.&apos;);
              assert.deepEqual(submissions[0], submission, &apos;Should match submission&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;Content-Range&apos;: &apos;0-0/1&apos;,
                  &apos;Range-Unit&apos;: &apos;items&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: [submission]
              };
            }
          };
        }
      },
      {
        name: &apos;Read Submission&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
          return formio.loadSubmission()
            .then((response) =&gt; {
              assert.deepEqual(response, submission, &apos;Submission should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: submission
              };
            }
          };
        }
      },
      {
        name: &apos;Update Submission&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
          const newSubmission = fastCloneDeep(submission);
          newSubmission.data.fieldLabel = chance.string();
          return formio.saveSubmission(newSubmission)
            .then((response) =&gt; {
              assert.deepEqual(response, submission, &apos;Submission should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
            method: &apos;PUT&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              submission = body;
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: submission
              };
            }
          };
        }
      },
      {
        name: &apos;Update Submission without ID&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}`);
          const newSubmission = fastCloneDeep(submission);
          newSubmission.data.fieldLabel = chance.string();
          return formio.saveSubmission(newSubmission)
            .then((response) =&gt; {
              assert.deepEqual(response, submission, &apos;Submission should match&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
            method: &apos;PUT&apos;,
            response(url, opts) {
              const body = JSON.parse(opts.body);
              submission = body;
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: submission
              };
            }
          };
        }
      },
      // // Actions
      // // Available Actions
      // // Action Info
      {
        name: &apos;Delete Submission&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}/submission/${submission._id}`);
          return formio.deleteSubmission()
            .then((response) =&gt; {
              assert.equal(response, &apos;OK&apos;, &apos;Submission should be deleted.&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}/submission/${submission._id}`,
            method: &apos;DELETE&apos;,
            response: {
              status: 200,
              body: &apos;OK&apos;,
              headers: {
                &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,
                &apos;x-jwt-token&apos;: userToken
              }
            }
          };
        }
      },
      {
        name: &apos;Delete Form&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}/form/${form._id}`);
          return formio.deleteForm()
            .then((response) =&gt; {
              assert.equal(response, &apos;OK&apos;, &apos;Submission should be deleted.&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/form/${form._id}`,
            method: &apos;DELETE&apos;,
            response: {
              status: 200,
              body: &apos;OK&apos;,
              headers: {
                &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,
                &apos;x-jwt-token&apos;: userToken
              }
            }
          };
        }
      },
      {
        name: &apos;Delete Project&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}`);
          return formio.deleteProject()
            .then((response) =&gt; {
              assert.equal(response, &apos;OK&apos;, &apos;Submission should be deleted.&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}`,
            method: &apos;DELETE&apos;,
            response: {
              status: 200,
              body: &apos;OK&apos;,
              headers: {
                &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,
                &apos;x-jwt-token&apos;: userToken
              }
            }
          };
        }
      },
      {
        name: &apos;Getting Projects&apos;,
        test() {
          return Formio.loadProjects()
            .then((projects) =&gt; {
              assert.equal(projects.length, 0, &apos;Should return no projects.&apos;);
              assert.equal(projects.skip, undefined, &apos;skip should be undefined.&apos;);
              assert.equal(projects.limit, undefined, &apos;limit should be undefined.&apos;);
              assert.equal(projects.serverCount, 0, &apos;serverCount should be 0.&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project`,
            method: &apos;GET&apos;,
            response() {
              return {
                headers: {
                  &apos;Content-Type&apos;: &apos;application/json&apos;,
                  &apos;Content-Range&apos;: &apos;*/0&apos;,
                  &apos;Range-Unit&apos;: &apos;items&apos;,
                  &apos;x-jwt-token&apos;: userToken
                },
                body: []
              };
            }
          };
        }
      },
      {
        name: &apos;Temporary Token&apos;,
        test() {
          const formio = new Formio(`/project/${project._id}`);
          return formio.getTempToken(200, &apos;GET:/current&apos;).then((tempToken) =&gt; {
            assert.equal(tempToken, userToken);
          });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/project/${project._id}/token`,
            method: &apos;GET&apos;,
            response() {
              return {
                status: 200,
                body: userToken,
                headers: {
                  &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,
                  &apos;x-jwt-token&apos;: userToken
                }
              };
            }
          };
        }
      },
      {
        name: &apos;Logging Out&apos;,
        test() {
          return Formio.logout()
            .then(() =&gt; {
              assert.equal(Formio.getToken(), null, &apos;Logged out&apos;);
            });
        },
        mock() {
          return {
            url: `${Formio.getBaseUrl()}/logout`,
            method: &apos;GET&apos;,
            response() {
              userToken = null;
              return {
                status: 200,
                body: &apos;OK&apos;,
                headers: {
                  &apos;Content-Type&apos;: &apos;text/plain; charset=utf-8&apos;,
                  &apos;x-jwt-token&apos;: &apos;&apos;
                }
              };
            }
          };
        }
      },
      {
        name: &apos;userPermissions method should give create_all permission&apos;,
        test() {
          const user = {
            _id: &apos;test_user_id&apos;,
            roles: [&apos;test_role_id&apos;]
          };

          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.edit, false);
              assert.equal(permissions.delete, false);
              assert.equal(permissions.read, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [
                      {
                        type: &apos;create_all&apos;,
                        roles: [&apos;test_role_id&apos;]
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give create_own permission&apos;,
        test() {
          const userId = &apos;test_user_id&apos;;
          const user = {
            _id: userId,
            roles: [&apos;test_role_id&apos;]
          };
          const submission = {
            owner: userId
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user, undefined, submission)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.edit, false);
              assert.equal(permissions.read, false);
              assert.equal(permissions.delete, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [
                      {
                        type: &apos;create_own&apos;,
                        roles: [&apos;test_role_id&apos;]
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give permissions for Anonymous role&apos;,
        test() {
          const user = {
            _id: false,
            roles: [],
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.edit, false);
              assert.equal(permissions.read, false);
              assert.equal(permissions.delete, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [
                      {
                        type: &apos;create_all&apos;,
                        roles: [&apos;test_anonymous_role_id&apos;]
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: [
                      {
                        _id: &apos;test_anonymous_role_id&apos;,
                        default: true
                      }
                    ]
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give all permissions for admin role&apos;,
        test() {
          const user = {
            roles: [&apos;test_admin_role&apos;],
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.read, true);
              assert.equal(permissions.edit, true);
              assert.equal(permissions.delete, true);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: []
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: [
                      {
                        _id: &apos;test_admin_role&apos;,
                        admin: true
                      }
                    ]
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give only group read permission for `read` level&apos;,
        test() {
          const user = {
            roles: [&apos;test_group_id&apos;],
          };
          const submission = {
            data: {
              groupField: {
                _id: &apos;test_group_id&apos;
              }
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user, undefined, submission)
            .then(permissions =&gt; {
              assert.equal(permissions.create, false);
              assert.equal(permissions.read, true);
              assert.equal(permissions.edit, false);
              assert.equal(permissions.delete, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [],
                    components: [
                      {
                        defaultPermission: &apos;read&apos;,
                        key: &apos;groupField&apos;
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give group read and create permissions for `create` level&apos;,
        test() {
          const user = {
            roles: [&apos;test_group_id&apos;],
          };
          const submission = {
            data: {
              groupField: {
                _id: &apos;test_group_id&apos;
              }
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user, undefined, submission)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.read, true);
              assert.equal(permissions.edit, false);
              assert.equal(permissions.delete, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [],
                    components: [
                      {
                        defaultPermission: &apos;create&apos;,
                        key: &apos;groupField&apos;
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give group read, create and edit permissions for `write` level&apos;,
        test() {
          const user = {
            roles: [&apos;test_group_id&apos;],
          };
          const submission = {
            data: {
              groupField: {
                _id: &apos;test_group_id&apos;
              }
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user, undefined, submission)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.read, true);
              assert.equal(permissions.edit, true);
              assert.equal(permissions.delete, false);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [],
                    components: [
                      {
                        defaultPermission: &apos;write&apos;,
                        key: &apos;groupField&apos;
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should give all group permissions for `admin` level&apos;,
        test() {
          const user = {
            roles: [&apos;test_group_id&apos;],
          };
          const submission = {
            data: {
              groupField: {
                _id: &apos;test_group_id&apos;
              }
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return formio.userPermissions(user, undefined, submission)
            .then(permissions =&gt; {
              assert.equal(permissions.create, true);
              assert.equal(permissions.read, true);
              assert.equal(permissions.edit, true);
              assert.equal(permissions.delete, true);
            });
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [],
                    components: [
                      {
                        defaultPermission: &apos;admin&apos;,
                        key: &apos;groupField&apos;
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
      {
        name: &apos;userPermissions method should handle submission with multiple groups&apos;,
        test() {
          const user1 = {
            roles: [&apos;test_group_id1&apos;],
          };
          const user2 = {
            roles: [&apos;test_group_id2&apos;],
          };
          const submission = {
            data: {
              groupField: [
                {
                  _id: &apos;test_group_id1&apos;
                },
                {
                  _id: &apos;test_group_id2&apos;
                }
              ]
            }
          };
          const formio = new Formio(`${Formio.getBaseUrl()}/testform`);
          return NativePromise.all([
            formio.userPermissions(user1, undefined, submission)
              .then(permissions =&gt; {
                assert.equal(permissions.create, false);
                assert.equal(permissions.read, true);
                assert.equal(permissions.edit, false);
                assert.equal(permissions.delete, false);
              }),
            formio.userPermissions(user2, undefined, submission)
              .then(permissions =&gt; {
                assert.equal(permissions.create, false);
                assert.equal(permissions.read, true);
                assert.equal(permissions.edit, false);
                assert.equal(permissions.delete, false);
              }),
          ]);
        },
        mock() {
          return [
            {
              url: `${Formio.getBaseUrl()}/testform`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    submissionAccess: [],
                    components: [
                      {
                        defaultPermission: &apos;read&apos;,
                        key: &apos;groupField&apos;
                      }
                    ]
                  },
                };
              }
            },
            {
              url: `${Formio.getBaseUrl()}/access`,
              method: &apos;GET&apos;,
              response() {
                return {
                  status: 200,
                  body: {
                    roles: []
                  }
                };
              }
            },
          ];
        }
      },
    ];

    tests.forEach(testCapability);
  });

  describe(&apos;Formio.currentUser&apos;, () =&gt; {
    let plugin = null;
    beforeEach(() =&gt; {
      plugin = {
        wrapStaticRequestPromise: sinon.spy((promise) =&gt; promise),
        staticRequest: sinon.spy(() =&gt; {
          // Return dummy user
          const userId = generateID();
          return NativePromise.resolve({
            _id: userId,
            created: new Date().toISOString(),
            modified: new Date().toISOString(),
            data: {
              email: &apos;user@place.com&apos;,
              name: &apos;user&apos;
            },
            externalIds: [],
            externalTokens: [],
            form: generateID(),
            owner: userId
          });
        })
      };
      Formio.registerPlugin(plugin, &apos;currentUserTestPlugin&apos;);
    });

    afterEach(() =&gt; {
      Formio.deregisterPlugin(plugin);
    });

    it(&apos;Initial currentUser() should make static request&apos;, (done) =&gt; {
      // Force token
      Formio.token = chance.string({ length: 30 });
      Formio.currentUser()
        .then(() =&gt; {
          assert.ok(plugin.staticRequest.calledOnce, &apos;staticRequest should be called once&apos;);
          done();
        });
      assert.ok(plugin.wrapStaticRequestPromise.calledOnce, &apos;wrapStaticRequestPromise should be called once&apos;);
    });

    it(&apos;Next currentUser() should return cached value&apos;, (done) =&gt; {
      // Clear token
      Formio.currentUser()
        .then(() =&gt; {
          assert.ok(!plugin.staticRequest.called, &apos;staticRequest should not be called&apos;);
          done();
        });
      assert.ok(plugin.wrapStaticRequestPromise.calledOnce, &apos;wrapStaticRequestPromise should be called once&apos;);
    });
  });
});
</code></pre>

</div>

<footer class="footer">
  Generated by <a href="https://esdoc.org">ESDoc<span data-ice="esdocVersion">(1.1.0)</span><img src="./image/esdoc-logo-mini-black.png"></a>
</footer>

<script src="script/search_index.js"></script>
<script src="script/search.js"></script>
<script src="script/pretty-print.js"></script>
<script src="script/inherited-summary.js"></script>
<script src="script/test-summary.js"></script>
<script src="script/inner-link.js"></script>
<script src="script/patch-for-local.js"></script>
</body>
</html>
